import axios from "axios";
import { Modal, message, notification } from "ant-design-vue";
import moment from "moment";
import store from "../store";
import db from "./localstorage";
moment.locale("zh-cn");

// 统一配置
let Axios = axios.create({
  baseURL: process.env.VUE_APP_API_BASE_URL,
  responseType: "json",
  validateStatus(status) {
    // 200 外的状态码都认定为失败
    return status === 200;
  }
});

// 拦截请求
Axios.interceptors.request.use(
  config => {
    // let expireTime = store.state.account.expireTime
    // let now = moment().format('YYYYMMDDHHmmss')
    // 有 token就带上
    if (store.state.account.token) {
      config.headers.Authentication = store.state.account.token;
    }
    return config;
  },
  error => {
    return Promise.reject(error);
  }
);

// 拦截响应
Axios.interceptors.response.use(
  config => {
    return config;
  },
  error => {
    if (error.response) {
      let data = error.response.data;
      let errorMessage =
        error.response.data === null
          ? "系统内部异常，请联系网站管理员"
          : error.response.data.message;
      const token = store.state.account.token;
      console.log("------异常响应------", error.response.status);
      console.log("------message------", data.message);

      switch (error.response.status) {
        // 服务器内部异常
        case 500:
          if (
            token &&
            (data.message.includes("token已失效") ||
              data.message.includes("token校验不通过"))
          ) {
            Modal.error({
              title: "认证失败",
              content: "登录已过期，请重新登录",
              okText: "重新登录",
              mask: false,
              onOk: () => {
                db.clear();
                location.reload();
              }
            });
          }
          break;
        // 网络超时
        case 504:
          notification.error({ message: "系统提示", description: "网络超时" });
          break;
        // 资源未找到
        case 404:
          notification.error({
            message: "系统提示",
            description: "很抱歉，资源未找到",
            duration: 4
          });
          break;
        // 拒绝访问
        case 403:
          notification.error({
            message: "系统提示",
            description: "拒绝访问",
            duration: 4
          });
          break;
        // 认证失败
        case 401:
          Modal.error({
            title: "认证失败",
            content: "登录已过期，请重新登录",
            okText: "重新登录",
            mask: false,
            onOk: () => {
              if (token) {
                request
                  .get(`/api/logout/${store.state.account.user.activeId}`)
                  .then(() => {
                    return new Promise((resolve, reject) => {
                      console.log(resolve, reject);
                      db.clear();
                      location.reload();
                    });
                  });
              } else {
                db.clear();
                location.reload();
              }
            }
          });
          break;
        default:
          notification.error({
            message: "系统提示",
            description: errorMessage,
            duration: 4
          });
          break;
      }
    }
    return Promise.reject(error);
  }
);

const request = {
  /**
   * post
   * @param url
   * @param params
   * @returns {Promise<AxiosResponse<any>>}
   */
  post(url, params) {
    return Axios.post(url, params, {
      transformRequest: [
        params => {
          let result = "";
          Object.keys(params).forEach(key => {
            if (
              !Object.is(params[key], undefined) &&
              !Object.is(params[key], null)
            ) {
              result +=
                encodeURIComponent(key) +
                "=" +
                encodeURIComponent(params[key]) +
                "&";
            }
          });
          return result;
        }
      ],
      headers: {
        "Content-Type": "application/x-www-form-urlencoded"
      }
    });
  },
  /**
   * put
   * @param url
   * @param params
   * @returns {Promise<AxiosResponse<any>>}
   */
  put(url, params) {
    return Axios.put(url, params, {
      transformRequest: [
        params => {
          let result = "";
          Object.keys(params).forEach(key => {
            if (
              !Object.is(params[key], undefined) &&
              !Object.is(params[key], null)
            ) {
              result +=
                encodeURIComponent(key) +
                "=" +
                encodeURIComponent(params[key]) +
                "&";
            }
          });
          return result;
        }
      ],
      headers: {
        "Content-Type": "application/x-www-form-urlencoded"
      }
    });
  },
  /**
   * get
   * @param url
   * @param params
   * @returns {Promise<AxiosResponse<any>>}
   */
  get(url, params) {
    let _params;
    if (Object.is(params, undefined)) {
      _params = "";
    } else {
      _params = "?";
      for (let key in params) {
        if (
          // eslint-disable-next-line no-prototype-builtins
          params.hasOwnProperty(key) &&
          params[key] !== null &&
          !Object.is(params[key], undefined)
        ) {
          _params += `${key}=${params[key]}&`;
        }
      }
    }
    return Axios.get(`${url}${_params}`);
  },
  /**
   * delete
   * @param url
   * @param params
   * @returns {Promise<AxiosResponse<any>>}
   */
  delete(url, params) {
    let _params;
    if (Object.is(params, undefined)) {
      _params = "";
    } else {
      _params = "?";
      for (let key in params) {
        // eslint-disable-next-line no-prototype-builtins
        if (params.hasOwnProperty(key) && params[key] !== null) {
          _params += `${key}=${params[key]}&`;
        }
      }
    }
    return Axios.delete(`${url}${_params}`);
  },
  /**
   * export
   * @param url
   * @param params
   * @param fileName
   * @returns {Promise<AxiosResponse<any>>}
   */
  export(url, params = {}, fileName) {
    message.loading("导出数据中");
    return Axios.post(url, params, {
      transformRequest: [
        params => {
          let result = "";
          Object.keys(params).forEach(key => {
            if (
              !Object.is(params[key], undefined) &&
              !Object.is(params[key], null)
            ) {
              result +=
                encodeURIComponent(key) +
                "=" +
                encodeURIComponent(params[key]) +
                "&";
            }
          });
          return result;
        }
      ],
      responseType: "blob"
    })
      .then(r => {
        console.log(r);
        const content = r.data;
        const blob = new Blob([content]);
        if ("download" in document.createElement("a")) {
          const elink = document.createElement("a");
          elink.download = fileName;
          elink.style.display = "none";
          elink.href = URL.createObjectURL(blob);
          document.body.appendChild(elink);
          elink.click();
          URL.revokeObjectURL(elink.href);
          document.body.removeChild(elink);
        } else {
          navigator.msSaveBlob(blob, fileName);
        }
      })
      .catch(r => {
        console.error(r);
        message.error("导出失败");
      });
  },
  /**
   * download
   * @param url
   * @param params
   * @param filename
   * @returns {Promise<AxiosResponse<any>>}
   */
  download(url, params, filename) {
    message.loading("文件传输中");
    return Axios.post(url, params, {
      transformRequest: [
        params => {
          let result = "";
          Object.keys(params).forEach(key => {
            if (
              !Object.is(params[key], undefined) &&
              !Object.is(params[key], null)
            ) {
              result +=
                encodeURIComponent(key) +
                "=" +
                encodeURIComponent(params[key]) +
                "&";
            }
          });
          return result;
        }
      ],
      responseType: "blob"
    })
      .then(r => {
        const content = r.data;
        const blob = new Blob([content]);
        if ("download" in document.createElement("a")) {
          const elink = document.createElement("a");
          elink.download = filename;
          elink.style.display = "none";
          elink.href = URL.createObjectURL(blob);
          document.body.appendChild(elink);
          elink.click();
          URL.revokeObjectURL(elink.href);
          document.body.removeChild(elink);
        } else {
          navigator.msSaveBlob(blob, filename);
        }
      })
      .catch(r => {
        console.error(r);
        message.error("下载失败");
      });
  },
  /**
   * upload
   * @param url
   * @param params
   * @returns {Promise<AxiosResponse<any>>}
   */
  upload(url, params) {
    return Axios.post(url, params, {
      headers: {
        "Content-Type": "multipart/form-data"
      }
    });
  }
};

export default request;
